package graph_viewer.structure;

import java.util.*;

import graph_viewer.util.*;

/**
	This class represent papers of IEEE_InfoVis.
*/
public class  Citation_Graph{	
	ArrayList
		the_paper_nodes,
		the_edges;	// an edge is a reference, which from_end is the artical_id of a citeer, and to_end is that of the citation. an edge is a string like: "acm123456, acm 654321"

	public Citation_Graph(){
		the_paper_nodes	= new ArrayList();
		the_edges		= new ArrayList();
	}

	public Citation_Graph( ArrayList a_paper_list, ArrayList a_edge_list ){
		set_paper_nodes( a_paper_list );		
		set_edges( a_edge_list );
	}

	//============================================================================
	// public methods
	//============================================================================
	
	
	public void add_a_paper( IEEE_Infovis_Paper a_paper ){
		this.the_paper_nodes.add( a_paper );

		//update_edge_list( a_paper );
	}
/*
	//convert this citation graph to a classical graph
	public void convert_citation_graph(){
		ArrayList
			node_list		= new ArrayList(), // Structure.Node
			edge_list	= new ArrayList(); //Structure.Edge

		for ( Iterator _i = get_paper_nodes().iterator(); _i.hasNext(); ){
			IEEE_Infovis_Paper a_paper	= (IEEE_Infovis_Paper)_i.next();

			Node a_node	 = convert_IEEE_Paper( a_paper );

			node_list.add( a_node );
		}

		for ( Iterator _i = the_edges.iterator(); _i.hasNext(); ){
			String a_citation_edge	= (String)_i.next();

			String 
				from_node_label	= an_edge.substring( a_citation_edge.indexOf( "," ) ),
				to_node_label	= an_edge.substring( a_citation_edge.indexOf( "," ) + 1,  an_edge.length() );

			Node from_node, to_node;

			for ( Iterator _j = node_list.iterator(); _j.hasNext(); ){
				Node a_node = (Node)_j.next();
				String node_label	= a_node.get_label();

				if  ( node_label.equals( from_node_label ) ){
					from_node = a_node;
				}else if ( node_label.equals( to_node_label ) ){
					to_node	= a_node;
				}
			}

			if ( from_node != null && to_node != null ){
				Edge an_edge	= new Edge( from_node, to_node );
				edge_list.add( an_edge );
			}
		}
	}
	
	//convert an IEEE_Paper to a Structure.Node
	private Node convert_IEEE_Paper( IEEE_Infovis_Paper a_paper ){
	 	Node a_node	 = new Node();

		a_node.set_label( a_paper.get_id() );
		a_node.set_brief_text( a_paper.get_authors().toString() );
		a_node.set_text( a_paper.get_title() );
		
		return a_node;
	}
*/
	public String toString(){
		StringBuffer a_citation_graph	= new StringBuffer( "A citation graph has " + the_paper_nodes.size() + " nodes, " +  the_edges.size() + " edges: \n" );

		/*for ( Iterator _i = the_edges.iterator(); _i.hasNext(); ){

			a_citation_graph.append( (String)_i.next() + "\n" );
		}*/

		for ( Iterator _i = the_paper_nodes.iterator(); _i.hasNext(); ){
			IEEE_Infovis_Paper a_paper	= (IEEE_Infovis_Paper)_i.next();
			a_citation_graph.append(a_paper.get_id() + ", at conferece: " + a_paper.get_source() + "\n" );
			
			/*String topic	= a_paper.get_topic();

			if ( topic.length() == 0 ){
				Debug.println( a_paper.get_id() + "has no topic!!!", 56 );
			}
			a_citation_graph.append(a_paper.get_id() + " has topic" + a_paper.get_topic() + " \n" );
			ArrayList refs	= a_paper.get_references();

			a_citation_graph.append(a_paper.get_id() + " has " + refs.size() + "refs: \n" );

			for ( Iterator _j = refs.iterator(); _j.hasNext(); ){
				String ref	 = (String)_j.next();
				a_citation_graph.append ("\t" + ref + "\n" );
			}*/

		}

		return a_citation_graph.toString();
	}
	//============================================================================
	// private methods
	//============================================================================
	// when a new paper node is added, update the edge list	
	// 1. new paper refer to existing papers
	// 2. existing papers to new papers
	private void update_edge_list( IEEE_Infovis_Paper a_paper ){
		update_existing_references( a_paper );
		add_new_references( a_paper );
	}

	private void update_existing_references( IEEE_Infovis_Paper a_paper ){		
		String an_artical_id	= a_paper.get_id();
		
		for ( Iterator _i = the_paper_nodes.iterator(); _i.hasNext(); ){
			IEEE_Infovis_Paper an_existing_paper	= (IEEE_Infovis_Paper)_i.next();
			String an_existing_artical_id	= an_existing_paper.get_id();

			ArrayList references	= a_paper.get_references();

			for ( Iterator _j = references.iterator(); _j.hasNext(); ){
				String an_existing_ref	= (String)_j.next();

				if ( an_existing_ref.equals( an_artical_id ) ){
					the_edges.add ( an_existing_artical_id + "," + an_artical_id );
				}
			}
		}
	}

	private void add_new_references( IEEE_Infovis_Paper a_paper ){
		String an_artical_id	= a_paper.get_id();
		ArrayList references	= a_paper.get_references();
		
		for ( Iterator _i = references.iterator(); _i.hasNext(); ){
			String a_ref	= (String)_i.next();

			for ( Iterator _j = the_paper_nodes.iterator(); _j.hasNext(); ){
				IEEE_Infovis_Paper an_existing_paper	= (IEEE_Infovis_Paper)_j.next();

				String an_existing_artical_id = an_existing_paper.get_id();

				if ( a_ref.equals( an_existing_artical_id ) ){
					the_edges.add ( an_artical_id + "," + an_existing_artical_id );
				}
			}
		}
	}

	//============================================================================
	// setter & getter
	//============================================================================
	public void set_paper_nodes( ArrayList a_paper_list ){
		this.the_paper_nodes	= new ArrayList( a_paper_list );
	}
	public ArrayList get_paper_nodes(){
		return this.the_paper_nodes;
	}

	public void set_edges( ArrayList an_edge_list ){
		this.the_edges	= new ArrayList( an_edge_list );
	}
	public ArrayList get_edges(){
		return this.the_edges;
	}
}	      